﻿using Microsoft.SharePoint.Client.Services;
using System.ServiceModel.Activation;
using Microsoft.SharePoint;
using System;
using System.Globalization;
using PepsiCo.Common;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using T2V.SharePoint.Common.Utilities.Camlex;
using T2V.SharePoint.Common.Extensions;
using System.Collections.Specialized;
using Microsoft.SharePoint.Utilities;
using System.Web;
using T2V.SharePoint.Common.Utilities;
using RecurrenceGenerator;

namespace PepsiCo.RBS.Services
{
    [BasicHttpBindingServiceMetadataExchangeEndpoint]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    public class RBSService : IRBSService
    {
        // To test this service, use the Visual Studio WCF Test client
        // set the endpoint to http://<Your server name>/_vti_bin/RBSService.svc/mex

        public RBSResult GetCalendarOverlap(string webUrl, string listName, string startDate, string startHour, string startMinutes, string endDate, string endHour, string endMinutes, string bookingRoom, string currentEventId,
            string isRecurred,
            string rFrequency, // Weekly or Monthly
            string rInterval, // every 1 week or every 3 months
            string rOptions, // week/month's options, split by ","
            string isAdmin
            )
        {
            string events = string.Empty;
            List<string> listResourceIDs = new List<string>();
            List<string> listUnavailableMeetingRoomIDs = new List<string>();
            string strAvailableMeetingRooms = string.Empty;

            try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite spSite = new SPSite(webUrl))
                    {
                        using (SPWeb spWeb = spSite.OpenWeb())
                        {
                            int lcid = (int)spWeb.Locale.LCID;
                            CultureInfo webCulture = new CultureInfo(lcid);

                            DateTime startDateTime = ParseDate(webCulture, startDate, startHour, startMinutes);
                            DateTime endDateTime = ParseDate(webCulture, endDate, endHour, endMinutes);

                            if (startDateTime < DateTime.Today && !(isRecurred == "1" && !string.IsNullOrEmpty(currentEventId)))
                            {
                                //return error
                                events = "The start date must be greater or equal today's date.";
                            }
                            else if (startDateTime > endDateTime)
                            {
                                events = "The start date and time are after the end date and time.";
                            }
                            else if (isAdmin == "0" && (startDateTime.Date > DateTime.Today.AddYears(1).LastDayOfMonthFromDateTime() || endDateTime.Date > DateTime.Today.AddYears(1).LastDayOfMonthFromDateTime()))
                            {
                                events = "The booking must be within 12 months of today's date.";
                            }
                            else
                            {
                                int bookingRoomId = int.Parse(bookingRoom);
                                int curEventId = string.IsNullOrEmpty(currentEventId) ? 0 : int.Parse(currentEventId);

                                SPList spListBookEvent = spWeb.Lists.TryGetList(listName);
                                
                                if (spListBookEvent != null)
                                {
                                    #region [Get recurrence dates]
                                    RecurrenceValues reValues = null;

                                    if (isRecurred == "1")
                                    {
                                        switch (rFrequency)
                                        {
                                            case "Weekly": // Weekly
                                                WeeklyRecurrenceSettings we;
                                                SelectedDayOfWeekValues selectedValues = new SelectedDayOfWeekValues();

                                                we = new WeeklyRecurrenceSettings(startDateTime.Date, endDateTime.Date);

                                                var arrWeeklyOptions = rOptions.Split(',');

                                                foreach (string option in arrWeeklyOptions)
                                                {
                                                    switch (option)
                                                    {
                                                        case "0":
                                                            selectedValues.Sunday = true;
                                                            break;
                                                        case "1":
                                                            selectedValues.Monday = true;
                                                            break;
                                                        case "2":
                                                            selectedValues.Tuesday = true;
                                                            break;
                                                        case "3":
                                                            selectedValues.Wednesday = true;
                                                            break;
                                                        case "4":
                                                            selectedValues.Thursday = true;
                                                            break;
                                                        case "5":
                                                            selectedValues.Friday = true;
                                                            break;
                                                        case "6":
                                                            selectedValues.Saturday = true;
                                                            break;
                                                    }
                                                }

                                                reValues = we.GetValues(int.Parse(rInterval), selectedValues);
                                                break;

                                            case "Monthly": // Monthly
                                                MonthlyRecurrenceSettings mo;
                                                mo = new MonthlyRecurrenceSettings(startDateTime.Date, endDateTime.Date);

                                                var arrMonthlyOptions = rOptions.Split(',');

                                                if (arrMonthlyOptions.Length == 1)
                                                    reValues = mo.GetValues(int.Parse(arrMonthlyOptions[0]), int.Parse(rInterval));
                                                else
                                                {
                                                    reValues = mo.GetValues((MonthlySpecificDatePartOne)int.Parse(arrMonthlyOptions[0]), (MonthlySpecificDatePartTwo)int.Parse(arrMonthlyOptions[1]), int.Parse(rInterval));
                                                }
                                                break;
                                        }
                                    }
                                    #endregion [Get recurrence dates]

                                    var startHourValue = startDateTime.Hour;
                                    var startMinuteValue = startDateTime.Minute;

                                    var endHourValue = endDateTime.Hour;
                                    var endMinuteValue = endDateTime.Minute;

                                    //Get month range due to startDate anfd endDate
                                    RecurrenceValues monthRanges = null;
                                    MonthlyRecurrenceSettings moRec;
                                    moRec = new MonthlyRecurrenceSettings(startDateTime.FirstDayOfMonthFromDateTime(), endDateTime.Date);
                                    monthRanges = moRec.GetValues(1, 1);

                                    foreach (DateTime firstDayInMonth in monthRanges.Values)
                                    {
                                        DateTime lastDayInMonth = firstDayInMonth.LastDayOfMonthFromDateTime();

                                        // Construct a query that expands recurring events
                                        SPQuery query = new SPQuery();
                                        query.ExpandRecurrence = true;
                                        query.CalendarDate = firstDayInMonth;

                                        if (curEventId == 0)
                                        {
                                            query.Query = @"<Where>
                                                            <DateRangesOverlap>
                                                                <FieldRef Name='EventDate' />
                                                                <FieldRef Name='EndDate' />
                                                                <FieldRef Name='RecurrenceID' />
                                                                <Value Type='DateTime' IncludeTimeValue='FALSE'><Month /></Value>
                                                            </DateRangesOverlap>
                                                        </Where>
                                                        <OrderBy><FieldRef Name='EventDate' /></OrderBy>";

                                        }
                                        else
                                        {
                                            query.Query = string.Format(@"<Where>
                                                                        <And>
                                                                            <Neq>
                                                                                <FieldRef Name='ID' />
                                                                                <Value Type='Counter'>{0}</Value>
                                                                            </Neq>
                                                                            <DateRangesOverlap>
                                                                                <FieldRef Name='EventDate' />
                                                                                <FieldRef Name='EndDate' />
                                                                                <FieldRef Name='RecurrenceID' />
                                                                                <Value Type='DateTime' IncludeTimeValue='FALSE'><Month /></Value>
                                                                            </DateRangesOverlap>
                                                                        </And>
                                                                    </Where>
                                                                    <OrderBy><FieldRef Name='EventDate' /></OrderBy>", curEventId.ToString());
                                        }

                                        SPListItemCollection calendarItems = spListBookEvent.GetItems(query);

                                        foreach (SPListItem item in calendarItems)
                                        {
                                            DateTime eventDate = DateTime.Parse(item["EventDate"].ToString());
                                            if (eventDate >= firstDayInMonth && eventDate < lastDayInMonth.AddDays(1))
                                            {
                                                if (isRecurred != "1")
                                                {
                                                    CheckOverlap(item, startDateTime, endDateTime, bookingRoomId, ref events, ref listResourceIDs, ref listUnavailableMeetingRoomIDs);
                                                }
                                                else
                                                {
                                                    foreach (DateTime reDate in reValues.Values)
                                                    {
                                                        DateTime reStartDate = reDate.Date + new TimeSpan(startHourValue, startMinuteValue, 0);
                                                        DateTime reEndDate = reDate.Date + new TimeSpan(endHourValue, endMinuteValue, 0);

                                                        CheckOverlap(item, reStartDate, reEndDate, bookingRoomId, ref events, ref listResourceIDs, ref listUnavailableMeetingRoomIDs);
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    if (events != string.Empty)
                                    {
                                        events = "Time Overlap Warning!<br/>Your selected time overlaps with the following booking(s):<br/><br/>" + events;
                                    }

                                    #region Get available meeting rooms
                                    //get available meeting rooms
                                    SPList spListMeetingRoom = spWeb.GetList(spWeb.ServerRelativeUrl.TrimEnd('/') + PepsiCoConstants.MeetingRoom.LIST_URL);

                                    string caml = string.Empty;
                                    var expressionsAnd = new List<Expression<Func<SPListItem, bool>>>();

                                    expressionsAnd.Add(x => (bool)x[PepsiCoConstants.MeetingRoom.IS_ACTIVE_COLUMN] == true);

                                    var arrayUnavailableMeetingRoomIDs = listUnavailableMeetingRoomIDs.Distinct().ToArray();

                                    for (int i = 0; i < arrayUnavailableMeetingRoomIDs.Length; i++ )
                                    {
                                        string id = arrayUnavailableMeetingRoomIDs[i];
                                        expressionsAnd.Add(x => x[SPBuiltInFieldId.ID] != (DataTypes.LookupId)id);
                                    }

                                    caml = Camlex.Query().WhereAll(expressionsAnd).OrderBy(x => x[SPBuiltInFieldId.Title] as Camlex.Asc).ToString();

                                    SPQuery spQuery = new SPQuery();
                                    spQuery.Query = caml;
                                    spQuery.ViewFields = "<FieldRef Name='Title'/>";

                                    SPListItemCollection listRooms = spListMeetingRoom.GetItems(spQuery);

                                    if (listRooms != null && listRooms.Count > 0)
                                    {
                                        foreach (SPListItem room in listRooms)
                                        {
                                            strAvailableMeetingRooms += room.Title + "; ";
                                        }

                                        strAvailableMeetingRooms = strAvailableMeetingRooms.Trim().Trim(';');
                                    }
                                    else
                                    {
                                        strAvailableMeetingRooms = "There are no available meeting rooms with these options.";
                                    }
                                    #endregion Get available meeting rooms
                                }
                            }
                            
                        }
                    }
                });

            }
            catch (Exception ex)
            {
                throw ex;
            }

            return new RBSResult { Message = events, UsedResourceIDs = String.Join(",", listResourceIDs.Distinct().ToArray()), AvailableMeetingRooms = strAvailableMeetingRooms };
        }

        public RBSWaitingListResult GetCalendarOverlapWaitingList(string webUrl, string listName, string startDate, string startHour, string startMinutes, string endDate, string endHour, string endMinutes, string bookingRoom, string currentEventId,
    string isRecurred,
    string rFrequency, // Weekly or Monthly
    string rInterval, // every 1 week or every 3 months
    string rOptions, // week/month's options, split by ","
    string isAdmin
    )
        {
            string events = string.Empty;
            //int overlapCount = -1;
            List<int> listOverlapIDs = new List<int>();

            try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite spSite = new SPSite(webUrl))
                    {
                        using (SPWeb spWeb = spSite.OpenWeb())
                        {
                            int lcid = (int)spWeb.Locale.LCID;
                            CultureInfo webCulture = new CultureInfo(lcid);

                            DateTime startDateTime = ParseDate(webCulture, startDate, startHour, startMinutes);
                            DateTime endDateTime = ParseDate(webCulture, endDate, endHour, endMinutes);

                            if (startDateTime < DateTime.Today && !(isRecurred == "1" && !string.IsNullOrEmpty(currentEventId)))
                            {
                                //return error
                                events = "The start date must be greater or equal today's date.";
                            }
                            else if (startDateTime > endDateTime)
                            {
                                events = "The start date and time are after the end date and time.";
                            }
                            else if (isAdmin == "0" && (startDateTime.Date > DateTime.Today.AddYears(1).LastDayOfMonthFromDateTime() || endDateTime.Date > DateTime.Today.AddYears(1).LastDayOfMonthFromDateTime()))
                            {
                                events = "The booking must be within 12 months of today's date.";
                            }
                            else
                            {
                                int bookingRoomId = int.Parse(bookingRoom);
                                int curEventId = string.IsNullOrEmpty(currentEventId) ? 0 : int.Parse(currentEventId);

                                SPList spListBookEvent = spWeb.Lists.TryGetList(listName);

                                if (spListBookEvent != null)
                                {
                                    #region [Get recurrence dates]
                                    RecurrenceValues reValues = null;

                                    if (isRecurred == "1")
                                    {
                                        switch (rFrequency)
                                        {
                                            case "Weekly": // Weekly
                                                WeeklyRecurrenceSettings we;
                                                SelectedDayOfWeekValues selectedValues = new SelectedDayOfWeekValues();

                                                we = new WeeklyRecurrenceSettings(startDateTime.Date, endDateTime.Date);

                                                var arrWeeklyOptions = rOptions.Split(',');

                                                foreach (string option in arrWeeklyOptions)
                                                {
                                                    switch (option)
                                                    {
                                                        case "0":
                                                            selectedValues.Sunday = true;
                                                            break;
                                                        case "1":
                                                            selectedValues.Monday = true;
                                                            break;
                                                        case "2":
                                                            selectedValues.Tuesday = true;
                                                            break;
                                                        case "3":
                                                            selectedValues.Wednesday = true;
                                                            break;
                                                        case "4":
                                                            selectedValues.Thursday = true;
                                                            break;
                                                        case "5":
                                                            selectedValues.Friday = true;
                                                            break;
                                                        case "6":
                                                            selectedValues.Saturday = true;
                                                            break;
                                                    }
                                                }

                                                reValues = we.GetValues(int.Parse(rInterval), selectedValues);
                                                break;

                                            case "Monthly": // Monthly
                                                MonthlyRecurrenceSettings mo;
                                                mo = new MonthlyRecurrenceSettings(startDateTime.Date, endDateTime.Date);

                                                var arrMonthlyOptions = rOptions.Split(',');

                                                if (arrMonthlyOptions.Length == 1)
                                                    reValues = mo.GetValues(int.Parse(arrMonthlyOptions[0]), int.Parse(rInterval));
                                                else
                                                {
                                                    reValues = mo.GetValues((MonthlySpecificDatePartOne)int.Parse(arrMonthlyOptions[0]), (MonthlySpecificDatePartTwo)int.Parse(arrMonthlyOptions[1]), int.Parse(rInterval));
                                                }
                                                break;
                                        }
                                    }
                                    #endregion [Get recurrence dates]

                                    var startHourValue = startDateTime.Hour;
                                    var startMinuteValue = startDateTime.Minute;

                                    var endHourValue = endDateTime.Hour;
                                    var endMinuteValue = endDateTime.Minute;

                                    //Get month range due to startDate anfd endDate
                                    RecurrenceValues monthRanges = null;
                                    MonthlyRecurrenceSettings moRec;
                                    moRec = new MonthlyRecurrenceSettings(startDateTime.FirstDayOfMonthFromDateTime(), endDateTime.Date);
                                    monthRanges = moRec.GetValues(1, 1);

                                    foreach (DateTime firstDayInMonth in monthRanges.Values)
                                    {
                                        DateTime lastDayInMonth = firstDayInMonth.LastDayOfMonthFromDateTime();

                                        // Construct a query that expands recurring events
                                        SPQuery query = new SPQuery();
                                        query.ExpandRecurrence = true;
                                        query.CalendarDate = firstDayInMonth;

                                        if (curEventId == 0)
                                        {
                                            query.Query = @"<Where>
                                                            <DateRangesOverlap>
                                                                <FieldRef Name='EventDate' />
                                                                <FieldRef Name='EndDate' />
                                                                <FieldRef Name='RecurrenceID' />
                                                                <Value Type='DateTime' IncludeTimeValue='FALSE'><Month /></Value>
                                                            </DateRangesOverlap>
                                                        </Where>
                                                        <OrderBy><FieldRef Name='EventDate' /></OrderBy>";

                                        }
                                        else
                                        {
                                            query.Query = string.Format(@"<Where>
                                                                        <And>
                                                                            <Neq>
                                                                                <FieldRef Name='ID' />
                                                                                <Value Type='Counter'>{0}</Value>
                                                                            </Neq>
                                                                            <DateRangesOverlap>
                                                                                <FieldRef Name='EventDate' />
                                                                                <FieldRef Name='EndDate' />
                                                                                <FieldRef Name='RecurrenceID' />
                                                                                <Value Type='DateTime' IncludeTimeValue='FALSE'><Month /></Value>
                                                                            </DateRangesOverlap>
                                                                        </And>
                                                                    </Where>
                                                                    <OrderBy><FieldRef Name='EventDate' /></OrderBy>", curEventId.ToString());
                                        }

                                        SPListItemCollection calendarItems = spListBookEvent.GetItems(query);

                                        //overlapCount = 0;

                                        foreach (SPListItem item in calendarItems)
                                        {
                                            DateTime eventDate = DateTime.Parse(item["EventDate"].ToString());
                                            if (eventDate >= firstDayInMonth && eventDate < lastDayInMonth.AddDays(1))
                                            {
                                                if (isRecurred != "1")
                                                {
                                                    CheckOverlapWaitingList(item, startDateTime, endDateTime, bookingRoomId, ref events, ref listOverlapIDs);
                                                }
                                                else
                                                {
                                                    foreach (DateTime reDate in reValues.Values)
                                                    {
                                                        DateTime reStartDate = reDate.Date + new TimeSpan(startHourValue, startMinuteValue, 0);
                                                        DateTime reEndDate = reDate.Date + new TimeSpan(endHourValue, endMinuteValue, 0);

                                                        CheckOverlapWaitingList(item, reStartDate, reEndDate, bookingRoomId, ref events, ref listOverlapIDs);
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    if (listOverlapIDs.Count >= 2)
                                    {
                                        events = "Time Overlap Warning!<br/>Your selected time overlaps with the following bookings in Waiting List:<br/><br/>" + events + "<b>There are " + listOverlapIDs.Count.ToString() + " waiting records for this room with this selected time. You cannot book anymore.</b>";
                                    }
                                    else
                                    {
                                        events = string.Empty;
                                    }

                                }
                            }

                        }
                    }
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return new RBSWaitingListResult { Message = events, OverlapCount = listOverlapIDs.Count.ToString() /*String.Join(",", listResourceIDs.Distinct().ToArray())*/ };
        }

        public string SendWarningEmail(string webUrl, string listId, string itemId)
        {
            string strBookUser = string.Empty;
            var ctx = HttpContext.Current;
            try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite spSite = new SPSite(webUrl))
                    {
                        using (SPWeb spWeb = spSite.OpenWeb())
                        {
                            SPList spListBookEvent = spWeb.Lists[new Guid(listId)];

                            if (spListBookEvent != null)
                            {
                                SPListItem itemBookEvent = spListBookEvent.GetItemById(int.Parse(itemId));

                                if (itemBookEvent != null)
                                {
                                    SPUser user = spWeb.EnsureUserByLookupValue(itemBookEvent[PepsiCoColumnId.BookEvent.User].ToString());
                                    strBookUser = user.Name;

                                    SPList spListMeetingRoom = spWeb.GetList(spWeb.ServerRelativeUrl.TrimEnd('/') + PepsiCoConstants.MeetingRoom.LIST_URL);
                                    SPListItem spItemMeetingRoom = spListMeetingRoom.GetItemById(Convert.ToInt32(itemBookEvent[PepsiCoColumnId.BookEvent.MeetingRoom].ToString().Split(new string[] { ";#" }, StringSplitOptions.RemoveEmptyEntries)[0]));
                                    string availableResources = string.Empty;
                                    string[] arrAR = spItemMeetingRoom[PepsiCoColumnId.MeetingRoom.AvailableResources].ToString().Split(new string[] { ";#" }, StringSplitOptions.RemoveEmptyEntries);
                                    for(int i = 1; i < arrAR.Length; i = i + 2)
                                    {
                                        availableResources += arrAR[i] + ", ";
                                    }
                                    availableResources = availableResources.Trim().Trim(',');

                                    SPList spListEmailTemplates = spWeb.GetList(spWeb.ServerRelativeUrl.TrimEnd('/') + PepsiCoConstants.EmailTemplate.LIST_URL);

                                    //string caml = string.Empty;
                                    //var expressionsAnd = new List<Expression<Func<SPListItem, bool>>>();

                                    //expressionsAnd.Add(x => ((string)x[PepsiCoConstants.EmailTemplate.CODE_COLUMN]) == "M001");

                                    //caml = Camlex.Query().WhereAll(expressionsAnd).ToString();

                                    //SPQuery queryEmailTemplate = new SPQuery();
                                    //queryEmailTemplate.Query = caml;
                                    //queryEmailTemplate.ViewFields = "<FieldRef Name='EmailSubject'/><FieldRef Name='EmailBody'/>";
                                    //queryEmailTemplate.RowLimit = 1;
                                    //SPListItemCollection listItemEmails = spListEmailTemplates.GetItems(queryEmailTemplate);

                                    //if (listItemEmails != null && listItemEmails.Count > 0)
                                    //{
                                        SPListItem itemEmail = spListEmailTemplates.GetItemById(1);
                                        string emailSubject = itemEmail[PepsiCoColumnId.EmailTemplate.EmailSubject].ToString();
                                        string emailRawBody = itemEmail[PepsiCoColumnId.EmailTemplate.EmailBody].ToString();

                                        string resources = string.Empty;
                                        string[] arrR = itemBookEvent[PepsiCoColumnId.BookEvent.ResourceRequest].ToString().Split(new string[] { ";#" }, StringSplitOptions.RemoveEmptyEntries);
                                        for (int i = 1; i < arrR.Length; i = i + 2)
                                        {
                                            resources += arrR[i] + ", ";
                                        }
                                        resources = resources.Trim().Trim(',');

                                        string emailResolvedBody = string.Format(emailRawBody
                                            , strBookUser
                                            , spItemMeetingRoom.Title
                                            , itemBookEvent.Title //Subject
                                            , Convert.ToDateTime(itemBookEvent[SPBuiltInFieldId.StartDate]).ToString("MMMM dd yyyy hh:mm tt")
                                            , Convert.ToDateTime(itemBookEvent[SPBuiltInFieldId.EndDate].ToString()).ToString("MMMM dd yyyy hh:mm tt")
                                            , availableResources
                                            , resources
                                            );
                                        HttpContext.Current = null;
                                        SPUtility.SendEmail(spWeb, true, false, user.Email, emailSubject, emailResolvedBody);
                                    //}

                                    spWeb.AllowUnsafeUpdates = true;
                                    try
                                    {
                                        using (DisableItemEvent scope = new DisableItemEvent())
                                        {
                                            itemBookEvent[PepsiCoColumnId.BookEvent.IsSentWarningEmail] = true;
                                            itemBookEvent.SystemUpdate(false);
                                        }
                                    }
                                    finally
                                    {
                                        spWeb.AllowUnsafeUpdates = false;
                                    }
                                }
                            }
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                HttpContext.Current = ctx;
            }

            return strBookUser;
        }

        private void CheckOverlap(SPListItem item, DateTime startDateTime, DateTime endDateTime, int bookingRoomId, ref string events, ref List<string> listResourceIDs, ref List<string> listUnavailableMeetingRoomIDs)
        {
            string eventTitle;

            bool timeOverlap = false;

            DateTime eventStartDateTime = DateTime.Parse(item["EventDate"].ToString());

            DateTime eventEndDateTime = DateTime.Parse(item["EndDate"].ToString());

            //if (item.ID != curEventId)
            //{

            eventTitle = (string)item["Title"];

            timeOverlap = false;

            //if newstartdate >= eStartDate and newStartDate < eEndDate
            if (startDateTime >= eventStartDateTime && startDateTime < eventEndDateTime)
            {
                timeOverlap = true;
            }

            //if newEndDate > eStartDate and newEndDate <= eEndDate
            else if (endDateTime > eventStartDateTime && endDateTime <= eventEndDateTime)
            {
                timeOverlap = true;
            }

            // if eStartDate >= newStartDate and eStartDate < newEndDate
            else if (eventStartDateTime >= startDateTime && eventStartDateTime < endDateTime)
            {
                timeOverlap = true;
            }

            // if eEndDate > newStartDate and eEndDate <= newEndDate
            else if (eventEndDateTime > startDateTime && eventEndDateTime <= endDateTime)
            {
                timeOverlap = true;
            }

            // if newStartDate = eStartDate and newEndDate = eEndDate
            else if (startDateTime == eventStartDateTime && endDateTime == eventEndDateTime)
            {
                timeOverlap = true;
            }


            if (timeOverlap == true)
            {
                if (item[PepsiCoColumnId.BookEvent.MeetingRoom] != null && new SPFieldLookupValue(item[PepsiCoColumnId.BookEvent.MeetingRoom].ToString()).LookupId == bookingRoomId)
                {
                    events += "Subject : " + eventTitle + "<br/>";
                    events += "Start Time: " + eventStartDateTime.ToString("dddd, MM/dd/yyyy hh:mm tt") + "<br/>End Time: " + eventEndDateTime.ToString("dddd, MM/dd/yyyy hh:mm tt") + "<br/>";
                    events += "Booked By: " + item["Author"].ToString().Split("#".ToCharArray())[1] + "<br/><br/>";
                }


                //get list of unavailable meeting room IDs
                if (item[PepsiCoColumnId.BookEvent.MeetingRoom] != null)
                {
                    listUnavailableMeetingRoomIDs.Add(new SPFieldLookupValue(item[PepsiCoColumnId.BookEvent.MeetingRoom].ToString()).LookupId.ToString());
                }


                //if timeOverlap, then get the resources have been requested to prevent double request
                if (item[PepsiCoColumnId.BookEvent.ResourceRequest] != null && !string.IsNullOrEmpty(item[PepsiCoColumnId.BookEvent.ResourceRequest].ToString()))
                {
                    string[] resouceRequest = item[PepsiCoColumnId.BookEvent.ResourceRequest].ToString().Split(new string[] { ";#" }, StringSplitOptions.RemoveEmptyEntries);

                    for (int i = 0; i < resouceRequest.Length; i = i + 2)
                    {
                        listResourceIDs.Add(resouceRequest[i]);
                    }
                }
            }
            //}
        }

        private void CheckOverlapWaitingList(SPListItem item, DateTime startDateTime, DateTime endDateTime, int bookingRoomId, ref string events, ref List<int> listOverlapIDs)
        {
            string eventTitle;

            bool timeOverlap = false;

            DateTime eventStartDateTime = DateTime.Parse(item["EventDate"].ToString());

            DateTime eventEndDateTime = DateTime.Parse(item["EndDate"].ToString());

            //if (item.ID != curEventId)
            //{

            eventTitle = (string)item["Title"];

            timeOverlap = false;

            //if newstartdate >= eStartDate and newStartDate < eEndDate
            if (startDateTime >= eventStartDateTime && startDateTime < eventEndDateTime)
            {
                timeOverlap = true;
            }

            //if newEndDate > eStartDate and newEndDate <= eEndDate
            else if (endDateTime > eventStartDateTime && endDateTime <= eventEndDateTime)
            {
                timeOverlap = true;
            }

            // if eStartDate >= newStartDate and eStartDate < newEndDate
            else if (eventStartDateTime >= startDateTime && eventStartDateTime < endDateTime)
            {
                timeOverlap = true;
            }

            // if eEndDate > newStartDate and eEndDate <= newEndDate
            else if (eventEndDateTime > startDateTime && eventEndDateTime <= endDateTime)
            {
                timeOverlap = true;
            }

            // if newStartDate = eStartDate and newEndDate = eEndDate
            else if (startDateTime == eventStartDateTime && endDateTime == eventEndDateTime)
            {
                timeOverlap = true;
            }


            if (timeOverlap == true)
            {
                if (item[PepsiCoColumnId.WaitEvent.MeetingRoom] != null && new SPFieldLookupValue(item[PepsiCoColumnId.WaitEvent.MeetingRoom].ToString()).LookupId == bookingRoomId)
                {
                    events += "Subject : " + eventTitle + "<br/>";
                    events += "Start Time: " + eventStartDateTime.ToString("dddd, MM/dd/yyyy hh:mm tt") + "<br/>End Time: " + eventEndDateTime.ToString("dddd, MM/dd/yyyy hh:mm tt") + "<br/>";
                    events += "Booked By: " + item["Author"].ToString().Split("#".ToCharArray())[1] + "<br/><br/>";

                    if (listOverlapIDs.IndexOf(item.ID) == -1)
                    {
                        listOverlapIDs.Add(item.ID);
                    }
                }
            }
            //}
        }

        private DateTime ParseDate(CultureInfo cultureInfo, string inputDate, string inputHour, string inputMinutes)
        {
            string sFullDate = string.Empty;
            sFullDate += inputDate;

            if (inputHour.IndexOf(':') > -1)
            {
                sFullDate += " " + inputHour + inputMinutes;
            }
            else if (inputHour.IndexOf(' ') > -1)
            {
                sFullDate += " " + inputHour.Split(' ')[0] + ":" + inputMinutes + " " + inputHour.Split(' ')[1];
            }

            return DateTime.ParseExact(sFullDate, cultureInfo.DateTimeFormat.ShortDatePattern + " " + cultureInfo.DateTimeFormat.ShortTimePattern, cultureInfo);
        }
    }

    public class RBSResult
    {
        public string Message { get; set; }
        public string UsedResourceIDs { get; set; }
        public string AvailableMeetingRooms { get; set; }
    }

    public class RBSWaitingListResult
    {
        public string Message { get; set; }
        public string OverlapCount { get; set; }
    }
}
